package lyj.springcloud.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.ribbon.proxy.annotation.Hystrix;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class PaymentService {

    @Value("${server.port}")
    private String port;
    /**
     * 正常服务
     * @return
     */
    public String paymentOk(String id) {
        return Thread.currentThread().getName() + "》》》端口： " + port + "支付服务  ok ： " + id;
    }

    /**
     * 服务降级：
     *   异常业务：
     *      业务异常，需要给客户端提供兜底方案
     *      业务出异常（不论是超时异常还是其他异常），都会触发定义的 fallbackMethod-服务降级方法
     *      如果异常被捕捉了，则无法触发fallbackMethod方法
     * @return
     */
    @HystrixCommand(fallbackMethod = "paymentTimeoutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")  //3秒钟以内就是正常的业务逻辑
    })
    public String paymentTimeout(String id) {
        // 其他异常
        int i = 10/0;
        // 超时异常
      /*  try {
            TimeUnit.MILLISECONDS.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        return Thread.currentThread().getName() + "》》》端口： " + port + "支付服务： " + id;
    }


    /**
     * 服务降级调用的方法，方法名必须与@HystrixCommand注解中的fallbackMethod属性值一致
     * @return
     */
    public String paymentTimeoutHandler(String id ) {
        return  Thread.currentThread().getName() + "》》》端口： " + port + "支付服务异常： " + id;
    }


    /**
     * 服务熔断
     *   配置：
     *      10秒内请求达到10次，失败率达到60% ，则开启熔断器
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "circuitBreakerHandler",commandProperties = {
             // @HystrixProperty的name属性参考类：HystrixCommandProperties.class
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),  //是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),   //请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),  //时间范围
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"), //失败率达到多少后跳闸
    })
    public String circuitBreaker(Integer id) {
        if (id < 0) throw new RuntimeException("id 并不能为负数！");
        return Thread.currentThread().getName() + "》》》端口： " + port + "支付服务成功： " + id;
    }

    /**
     * 熔断器开启后的服务降级方法
     * @param id
     * @return
     */
    public String circuitBreakerHandler(Integer id) {
        return "当前支付服务不可用";
    }

}
